home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
netconf
/
host.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-03
|
11KB
|
426 lines
#include <stdio.h>
#include <string.h>
#include "netconf.h"
#include "internal.h"
#include "../xconf/xconf.h"
#include "../dnsconf/dnsconf.h"
#include "netconf.m"
static NETCONF_HELP_FILE help_thishost ("thishost");
/*
Compose one entry of the menu.
Simply add the current value to the menu string
Return dst.
*/
char *menu_setupopt(
char *dst,
const char *menu,
const char *curval)
{
if (curval[0] == '\0') curval = "Not set";
sprintf (dst,"%s (%s)",menu,curval);
return dst;
}
static void netconf_setoneinter (
DIALOG &dia,
INTER_INFO &itf,
const char *title)
{
dia.newf_title ("",title);
dia.newf_str (MSG_U(F_PRIMNAME,"Primary name + domain"),itf.name);
dia.newf_str (MSG_U(F_ALIASES,"Aliases (opt)"),itf.others);
dia.newf_str (MSG_U(F_IPADR,"IP address"),itf.ipaddr);
dia.newf_str (MSG_U(F_NETADR,"Network address (opt)"),itf.network);
dia.newf_str (MSG_U(F_NETMASK,"Netmask (opt)"),itf.netmask);
}
const int NB_ADAPTOR=4;
/*
Validate IP number. An empty string is ok here.
*/
static bool host_validip(const char *aip, bool ishost)
{
bool ret = true;
if (aip[0] != '\0') ret = device_validip(aip,ishost);
return ret;
}
/*
Validate the user input for one interface
*/
static void netconf_itfok(INTER_INFO &itf, const char *msg, char *status)
{
int name_empty = itf.name.is_empty();
int other_empty = itf.others.is_empty();
int ip_empty = itf.ipaddr.is_empty();
if (ip_empty){
if (!name_empty || !other_empty){
strcat (status,msg);
strcat (status,MSG_U(E_NEEDIP
,"\n\tYou must provide the IP number\n"
"\tsince you provided a name\n"));
}
}else{
char lstatus[1000];
lstatus[0] = '\0';
if (!device_validip(itf.ipaddr.get(),true)){
strcat (lstatus,MSG_U(F_IVLDIP,"\tInvalid host IP number\n"));
}
if (!host_validip(itf.network.get(),false)){
strcat (lstatus,MSG_U(F_IVLDNETIP,"\tInvalid network IP number\n"));
}
if (!host_validip(itf.netmask.get(),false)){
strcat (lstatus,MSG_U(E_IVLMASK,"\tInvalid netwask\n"));
}
if (lstatus[0] != '\0'){
strcat (status,msg);
strcat (status,"\n");
strcat (status,lstatus);
}
}
}
static void netconf_checknonet(INTER_INFO &itf)
{
/* #Specification: netconf / basic host info / no IP for eth0
If the user do no put any IP address for the
first adaptor (ETH0), it may be because it is
a mistake, or because no network is available.
In the later case, a good idea is to enter
the IP number 127.0.0.1. This has the advantage
that local networking will work (eg. export DISPLAY=host:0).
We can't assume that this is what the user intent. One
thing is sure, it is better to have a IP address there.
So we are asking for a confirmation to the user.
*/
if (itf.ipaddr.is_empty()
&& xconf_yesno (MSG_U(Q_NOIP,"Are you sure")
,MSG_U(I_NOIP
,"No IP address was entered for the first\n"
"ethernet adaptor. Either it is a mistake\n"
"(you forgot) or you don't have a network\n"
"adaptor at all.\n"
"\n"
"If you don't have any network adaptor,\n"
"it is a good idea to enter the IP number\n"
"127.0.0.1, which correspond to a dummy\n"
"internal network. This may help later with\n"
"network aware application such as X11.\n"
"\n"
"Do you want me to enter 127.0.0.1 for you ?")
,help_thishost)==MENU_YES){
itf.ipaddr.setfrom ("127.0.0.1");
}
}
/*
Edit the spec of the current host.
Return -1 if any error or the user abort the process.
*/
static int netconf_edithost(HOSTINFO &info)
{
/* #Specification: netconf / this host setup
The user can change fields for each adaptor.
#
primary name of this machine/adaptor
aliase names of this machine/adaptor
IP address
Network
Netmask
#
*/
int ret = -1;
int nofield = 0;
DIALOG dia;
int i;
static const char *tbmsg[]={
MSG_U(T_FIRSTETH,"First ethernet adaptor"),
MSG_U(T_SECONDETH,"Second ethernet adaptor"),
MSG_U(T_THIRDETH,"Third ethernet adaptor"),
MSG_U(T_FOURTHETH,"Fourth ethernet adaptor")
};
for (i=0; i<NB_ADAPTOR; i++){
netconf_setoneinter (dia,info.a[i],tbmsg[i]);
}
while (1){
if (dia.edit(
MSG_U(T_THISHOST,"This host basic configuration")
,MSG_U(I_THISHOST
,"You are allowed to control the parameters\n"
"which are specific to this host and related\n"
"to its main connection to the local network\n")
,help_thishost.getpath()
,nofield) != MENU_ACCEPT){
break;
}else{
/* We must validate the input somehow */
char status[1000];
status[0] = '\0';
netconf_checknonet(info.a[0]);
for (i=0; i<NB_ADAPTOR; i++){
netconf_itfok(info.a[i],tbmsg[i],status);
}
if (status[0] == '\0'){
ret = 0;
break;
}else{
xconf_error ("%s",status);
}
}
}
if (ret == -1) dia.restore();
return ret;
}
/*
Make sure the loghost alias is in str. Add it if missing.
*/
static void host_chkloghost(SSTRING &st, const char *loghost)
{
/* #Specification: netconf / host alias / loghost
netconf make sure that the alias "loghost" is
always set for the current host. If it is missing
it will be added. netconf use this internally to
locate the host definition.
*/
if (!host_lookupother(st.get(),loghost)){
char buf[1000];
sprintf (buf,"%s %s",st.get(),loghost);
st.setfrom (buf);
}
}
static void netconf_loadinfo (
INTER_INFO &itf,
HOSTS &hosts,
NETWORKS &networks,
const char *spcnamealias, // Special alias NAM_ETHx_NAME
const char *netname,
const char *mskname)
{
HOST *hst = hosts.getitem (spcnamealias);
HOST *net = networks.getitem (netname);
HOST *msk = networks.getitem (mskname);
if (hst != NULL){
itf.ipaddr.setfrom(hst->getipnum());
itf.others.setfrom(hst->getothers());
// It is possible that an entry only have the alias name
// There is no way to tell this just by reading /etc/hosts
// The primary name is simply the first of the list
// If the primary name is the special alias (loghost), we
// organise things here.
const char *name1 = hst->getname1();
if (strcmp(name1,spcnamealias)==0){
itf.others.append (" ");
itf.others.append (spcnamealias);
}else{
itf.name.setfrom (name1);
}
}
if (net != NULL) itf.network.setfrom(net->getipnum());
if (msk != NULL) itf.netmask.setfrom(msk->getipnum());
}
static void netconf_saveinfo (
INTER_INFO &itf,
HOSTS &hosts,
NETWORKS &networks,
const char *forcealias,
const char *netname,
const char *mskname)
{
HOST *hst = hosts.getitem (forcealias);
HOST *net = networks.getitem (netname);
HOST *msk = networks.getitem (mskname);
if (!itf.name.is_empty()
|| !itf.others.is_empty()
|| !itf.ipaddr.is_empty()){
host_chkloghost(itf.others,forcealias);
if (hst == NULL){
hst = new HOST;
hosts.add (hst);
}
hst->setname1 (itf.name.get());
hst->setipnum (itf.ipaddr.get());
hst->setothers(itf.others.get());
}else if (hst != NULL){
hosts.remove (hst);
delete hst;
}
if (!itf.network.is_empty()){
if (net == NULL){
net = new NETWORK;
networks.add (net);
}
net->setname1 (netname);
net->setipnum (itf.network.get());
}else if (net != NULL){
networks.remove (net);
delete net;
}
if (!itf.netmask.is_empty()){
if (msk == NULL){
msk = new NETWORK;
networks.add (msk);
}
msk->setname1 (mskname);
msk->setipnum (itf.netmask.get());
}else if (msk != NULL){
networks.remove (msk);
delete msk;
}
}
DEVICE_NAME_INFO dev_name_info[]={
{NAM_ETH0_LOGHOST,NAM_ETH0_NETWORK,NAM_ETH0_NETMASK},
{NAM_ETH1_LOGHOST,NAM_ETH1_NETWORK,NAM_ETH1_NETMASK},
{NAM_ETH2_LOGHOST,NAM_ETH2_NETWORK,NAM_ETH2_NETMASK},
{NAM_ETH3_LOGHOST,NAM_ETH3_NETWORK,NAM_ETH3_NETMASK},
};
/*
Load all basic information for all the adaptor from
/etc/hosts and /etc/networks
Return -1 if any error.
*/
static int netconf_loadinfos(
HOSTS &hosts,
NETWORKS &networks,
HOSTINFO &info)
{
int ret = -1;
if (hosts.read () != -1
&& networks.read() != -1){
int i;
for (i=0; i<NB_ADAPTOR; i++){
netconf_loadinfo (info.a[i],hosts,networks
,dev_name_info[i].host
,dev_name_info[i].net
,dev_name_info[i].mask);
}
ret = 0;
}
return ret;
}
/*
Load all basic information for all the adaptors from
/etc/hosts and /etc/networks
Return -1 if any error.
*/
int netconf_loadinfos(HOSTINFO &info)
{
HOSTS hosts;
NETWORKS networks;
return netconf_loadinfos(hosts,networks,info);
}
/*
Update the local DNS (if present) from the host information
*/
static void netconf_updatedns(HOSTINFO &info, int silent)
{
const char *tbip[NB_ADAPTOR];
int nbip = 0;
int ok = 0;
for (int i=0; i<NB_ADAPTOR; i++){
INTER_INFO *itf = &info.a[i];
if (!itf->ipaddr.is_empty()){
const char *ip = itf->ipaddr.get();
if (itf->name.is_empty()){
tbip[nbip++] = ip;
}else{
const char *tb[1];
tb[0] = ip;
ok |= dnsconf_condset (itf->name.get(),tb,1);
}
}
}
if (nbip > 0 && !info.a[0].name.is_empty()){
ok |= dnsconf_condset (info.a[0].name.get(),tbip,nbip);
}
if (ok && !silent){
xconf_notice(MSG_U(N_DNSUPDATED,"The DNS has been updated"));
}
}
/*
Update the local DNS (if present) from the host information
*/
void netconf_updatedns()
{
HOSTINFO info;
if (netconf_loadinfos(info)!=-1){
netconf_updatedns(info,1);
}
}
/*
Edit the spec of the current host
*/
void netconf_edithost()
{
/* #Specification: hostname / where is it stored
netconf use the plain /etc/hosts file to store
more of the name information. There is no other
file such as /etc/hostname or /etc/HOSTNAME.
netconf assume that special entries in /etc/hosts
will have known alias name. It will enforce the presence
of those alias name.
The primary name of the machine will be taken from
the entry which the alias "loghost". This name and
IP number will be used for the first ethernet adaptor (ETH0).
The second ethernet adaptor will be located from the
entry having the alias eth1_loghost. The third ethernet
adaptor spec will be located from the entry having the
alias eth2_loghost.
*/
/* #Specification: adaptor setup / Token ring and others
netconf does not manage such systems for now.
*/
HOSTS hosts;
NETWORKS networks;
HOSTINFO info;
if (netconf_loadinfos(hosts,networks,info)!=-1){
if (netconf_edithost (info) != -1){
for (int i=0; i<NB_ADAPTOR; i++){
netconf_saveinfo (info.a[i],hosts,networks
,dev_name_info[i].host
,dev_name_info[i].net
,dev_name_info[i].mask);
}
hosts.write();
networks.write ();
/* #Specification: netconf / basic host info / DNS
Each time we update the basic host info
(name and IP number of the adaptor), we
synchronise the info in the DNS on this
machine is one is available.
This is done silently. Maybe we should
let the user decide if he wants to update
the DNS from that info. Why ?
*/
netconf_updatedns(info,0);
}
}
}